package util;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.TreeSet;

import util.file.FileParserException;
import data.obj.CombatResult;
import data.obj.CriticalResult;
import data.reader.CriticalReader;
import data.reader.WeaponTableReader;

public class ArmsLaw
{
	HashMap<String, String[][]> armsLawHM = new HashMap<String, String[][]>();
	HashMap<String, CriticalResult> criticalHM = new HashMap<String, CriticalResult>();

	public ArmsLaw() throws FileParserException
	{
		inizialize();
	}

	private void inizialize() throws FileParserException
	{
		// READ Weapon table
		String path = "src/data/table/weapon/";
		File dir = new File(path);
		String[] files = dir.list();
		for (String f : files)
		{
			File nodir = new File(path+f);
			if(nodir.isDirectory())
				continue;
			WeaponTableReader wtr = new WeaponTableReader(path + f);
			wtr.process();
			String[][] table = wtr.getTable();
			String weaponName = f.substring(0, f.indexOf(".txt"));
			armsLawHM.put(weaponName, table);

		}

		// READ Critical table

		path = "src/data/table/weapon/critical/";
		dir = new File(path);
		files = dir.list();
		for (String f : files)
		{
			File nodir = new File(path+f);
			if(nodir.isDirectory())
				continue;
			//read File
			String CritName = f.substring(0, f.indexOf(".txt"));
			CriticalReader cr = new CriticalReader(path + f);
			cr.process();
			ArrayList<CriticalResult> critA = cr.get();
			
			//Fill HashMap
			for (CriticalResult c : critA)
			{
				criticalHM.put(CritName + c.getSeverity() + c.getRoll(), c);
			}
			
			//Duplicate values for roll not present
			CriticalResult value=null;
			for (String sev : new String[] { "A", "B", "C", "D", "E" })
			{
				for (int roll = 1; roll <= 100; roll++)
				{
					String newKey=CritName+sev+roll;
					CriticalResult keyValues=criticalHM.get(newKey);
					if (value!=null)
					{
						if(keyValues==null){
							criticalHM.put(newKey, value);
						}
					}
					else
					{
						if(keyValues!=null)
						{
							for (int nRoll = 1; nRoll < roll; nRoll++)
							{
								criticalHM.put(CritName+sev+nRoll, keyValues);
							}
							value=keyValues;
							
						}
					}
				}

			}
//			for(String key : criticalHM.keySet())
//			{
//				System.out.println(key+" \t"+criticalHM.get(key));
//				
//			}

		}
	}

	public CombatResult battleResult(String weapon, int attackRoll, int at)
	{
		String res = "";
		String[][] table = armsLawHM.get(weapon);
		if (attackRoll > 150)
			attackRoll = 150;
		if (attackRoll < 0)
			attackRoll = 0;
		int roll = 150 - attackRoll;
		int att = 20 - at;
		res = table[roll][att];
		String critSeverity = "";
		String criticalType = "";
		int hit = 0;
		CriticalResult criticalResult = new CriticalResult ();
		if (res.substring(res.length() - 1).matches("[0-9]"))
			hit = Integer.parseInt(res);
		else
		{
			hit = Integer.parseInt(res.substring(0, 2));
			critSeverity = res.substring(res.length() - 2, res.length() - 1);
			criticalType = GetCompletename(res.substring(res.length() - 1));
			int rollCrit = (int) Dice.D100();
			criticalResult=criticalHM.get(criticalType+critSeverity+rollCrit);
			criticalResult.setSeverity(critSeverity);
			criticalResult.setRoll(rollCrit);
			
		}
		CombatResult combatResult = new CombatResult(hit, criticalResult);
		// System.out.println(hit);
		// System.out.println(criticalClass);
		// System.out.println(criticalType);

		return combatResult;
	}

	private String GetCompletename(String t)
    {
	    String res ="";
	    if(t.equalsIgnoreCase("P"))
	    	res="PunctureCritical";
	    if(t.equalsIgnoreCase("K"))
	    	res="KrushCritical";
	    if(t.equalsIgnoreCase("S"))
	    	res="SlashCritical";
	    return res;
    }

}
